有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java测试没有单元测试调用的私有方法

在我的Java应用程序中,我想测试以下公共方法:

@Override
public List<ProductDTO> findByZoneOffset(final int zoneOffset) {
    final List<String> zoneIdList = getTimeZonesByZoneOffset(zoneOffset);
   
    final List<UUID> productConfigUuidList = 
        productConfigRepository.findAllUuidByZoneIdIn(zoneIdList);
    final List<Product> products = 
        productRepository.findAllBySiteConfigUuidIn(productConfigUuidList);

    return getProductDTOList(product);
}

有一个私有方法称为前一个公共方法:

private static List<String> getTimeZonesByZoneOffset(final int zoneOffset) {
    return ZoneId.getAvailableZoneIds()
            .stream()
            .filter(zoneId -> ZoneId.of(zoneId)
                    .getRules()
                    .getOffset(Instant.now())
                    .equals(ZoneOffset.ofHours(zoneOffset)))
            .sorted()
            .collect(Collectors.toList());
}

我为测试findByZoneOffset()方法创建了以下单元测试然而,我不能像在服务方法中那样为zoneIdList计算相同的值(getTimeZonesByZoneOffset),因此服务中的productConfigUuidList值返回空列表

@Test
public void test_findByZoneOffset() {
    final int numRecords = 3;
    final List<Product> productList = new ArrayList<>();

    final List<String> zoneIdList = new ArrayList<>();
    zoneIdList.add("Africa/Nairobi");
    zoneIdList.add("Asia/Baghdad");
    zoneIdList.add("Europe/Moscow");

    final List<UUID> productConfigUuidList = new ArrayList<>();
    final List<ProductConfig> productConfigList = new ArrayList<>();

    for (int i = 0; i < numRecords; i++) {
        final Product product = new Product();
        final ProductConfig productConfig = new ProductConfig();
        productConfig.setZoneId(zoneIdList.get(i));
        productConfigUuidList.add(productConfig.getUuid());
        productConfigList.add(productConfig);
        product.setProductConfigUuid(productConfig.getUuid());
        productList.add(product);
    }

    when(productConfigRepository.findAllUuidByZoneIdIn(zoneIdList))
        .thenReturn(productConfigUuidList);
    when(productRepository.findAllBySiteConfigUuidIn(productConfigUuidList))
        .thenReturn(productList);
    when(productRepository.findAll(any(ProductCriteriaRequest.class)))
        .thenReturn(productList);
    when(productConfigRepository.findAllByUuidIn(anyList()))
        .thenReturn(productConfigList);

    final List<ProductDTO> productDTOList = 
        productService.findByZoneOffset(numRecords);

    for (int i = 0; i < numRecords; i++) {
        assertEquals(zoneIdList.get(i), 
            productDTOList.get(i).getConfig().getZoneId());
    }
}

那么,我应该如何在不调用私有方法的情况下,用与服务方法相同的值模拟测试方法中的zoneIdList

请注意,私有方法是static,即使我将其移动到我的Util类并使其成为public,我也不确定是否可以测试它


共 (1) 个答案

  1. # 1 楼答案

    您可以创建另一个受保护的方法(包或子类专用)。这个新方法只调用private方法

    然后添加一个单元测试类,该类驻留在同一个包中,可以测试该私有方法

    在代码中,这看起来和

    private static List<String> getTimeZonesByZoneOffset(final int zoneOffset) {
        return ...
    }
    
    protected static List<String> getTimeZonesByZoneOffset2(final int zoneOffset) {
        return getTimeZonesByZoneOffset(zoneOffset);
    }
    

    然后为GetTimeZoneByZoneOffset2编写一个单元测试